import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class CustomClassLoader extends ClassLoader {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        CustomClassLoader customClassLoader = new CustomClassLoader();
        Class<?> hello = customClassLoader.findClass("Hello");
        // 反射调用hello方法
        Method[] declaredMethods = hello.getDeclaredMethods();
        Method[] methods = hello.getMethods();
        for (Method method : declaredMethods) {
            System.out.println("declaredMethods:" + method.getName());
        }
        for (Method method : methods) {
            System.out.println("method:" + method.getName());
        }
        Object instance = hello.getDeclaredConstructor().newInstance();
        Method method = hello.getMethod("hello");
        method.invoke(instance);
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        InputStream helloStream = this.getClass().getClassLoader().getResourceAsStream("Hello.xlass");
        byte[] classBytes = null;
        try {
            classBytes = new byte[helloStream.available()];
            helloStream.read(classBytes);
            for (int i = 0; i < classBytes.length; i++) {
                classBytes[i] = (byte) (255 - classBytes[i]);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return defineClass(name, classBytes, 0, classBytes.length);
    }
}
